package org.zxw.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.zxw.mapper.TrainingPlanMapper;
import org.zxw.pojo.entity.TrainingPlan;
import org.zxw.service.TrainingPlanService;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@Service
@Slf4j
public class TrainingPlanServiceImpl implements TrainingPlanService {
    private final TrainingPlanMapper planMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    public TrainingPlanServiceImpl(TrainingPlanMapper planMapper, RedisTemplate<String, Object> redisTemplate) {
        this.planMapper = planMapper;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 根据目标推荐训练计划
     * @param goal
     * @param limit
     * @return
     */
    public List<TrainingPlan> recommendByGoal(String goal, int limit) {
        String cacheKey = "plan:goal:" + goal + ":" + limit;
        return getWithCache(cacheKey, () -> planMapper.selectByGoal(goal, limit));
    }

    /**
     * 根据目标和难度推荐训练计划
     * @param goal
     * @param difficulty
     * @param limit
     * @return
     */
    public List<TrainingPlan> recommendByGoalAndDifficulty(String goal, String difficulty, int limit) {
        String cacheKey = String.format("plan:goal:%s:difficulty:%s:%d", goal, difficulty, limit);
        return getWithCache(cacheKey, () -> planMapper.selectByGoalAndDifficulty(goal, difficulty, limit));
    }

    /**
     * 根据BMI和难度推荐训练计划
     * @param bmi
     * @param difficulty
     * @param limit
     * @return
     */
    public List<TrainingPlan> recommendByBmi(double bmi, String difficulty, int limit) {
        String cacheKey = String.format("plan:bmi:%.1f:difficulty:%s:%d", bmi, difficulty, limit);
        return getWithCache(cacheKey, () -> planMapper.selectByBmi(bmi, difficulty, limit));
    }
    
    // 缓存通用处理
    private List<TrainingPlan> getWithCache(String cacheKey, Supplier<List<TrainingPlan>> dbSupplier) {
        try {
            // 尝试从缓存获取
            Object cached = redisTemplate.opsForValue().get(cacheKey);
            if (cached != null) {
                log.info("从缓存中获取数据");
                return (List<TrainingPlan>) cached;
            }
            
            // 从数据库获取
            List<TrainingPlan> plans = dbSupplier.get();
            
            // 存入缓存，设置1小时过期
            if (plans != null && !plans.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, plans, 1, TimeUnit.HOURS);
                log.info("缓存刷新成功");
            }
            return plans;
        } catch (Exception e) {
            // 缓存出错时降级直接查数据库
            log.info("缓存出错，降级查询数据库", e);
            return dbSupplier.get();
        }
    }
    
    // 刷新缓存
    public void refreshCache(String goal) {
        String pattern = "plan:goal:" + goal + ":*";
        Set<String> keys = redisTemplate.keys(pattern);
        if (keys != null) {
            redisTemplate.delete(keys);
        }
    }
}